/*
 * PhotonRTOS础光实时操作系统 -- 定时器驱动
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Xueming Dong <dongxueming@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include <asm/types.h>
#include <photon/init.h>
#include <photon/irq.h>
#include <photon/sched.h>
#include <photon/smp.h>
#include <photon/init_integrity.h>
#include <asm/arm_arch_timer.h>
#include <asm/arch_timer.h>
#include <asm/cputype.h>
#include <asm/io.h>
#include <autosar/counter_internal.h>
#include <autosar/internal.h>

#include <asm/io.h>
#include <asm/cputype.h>

#include <photon/time.h>
#include <asm/smp.h>
#include <photon/smp_lock.h>


/**
 * 声明中断相关信息
 *
 */
void cortexm3_timer_handler(void);

void vPortSVCHandler(void);
void vPortSVCHandler(void)
{
	printk("vPortSVCHandler\n");
}

void xPortPendSVHandler(void);
void xPortPendSVHandler(void)
{
	printk("xPortPendSVHandler\n");
}

void xPortSysTickHandler(void);
void xPortSysTickHandler(void)
{
	do_hard_irq(73, NULL);
}

void cortexm3_timer_handler(void)
{
	static int count = 0;

	if (count % 1000 == 0)
		pr_debug("cortexm3_timer_handler cpu\n");
	count++;

	add_jiffies_64(1);
	IncrementHardwareCounter(smp_processor_id());
}

DeclareInterrupt(cortexm3_timer_handler, 73, HWIRQ_TYPE_EDGE_RISING, 1000, 1, true);


struct irq_desc *os_irq_desc[NR_IRQS] = {
	[0] = &ISR_ATTR(cortexm3_timer_handler),
	NULL,
};

/* 设置systemtick 为 1ms */
#define configSYSTICK_CLOCK_HZ		(20000000)
#define configTICK_RATE_HZ          (1000)

#define SysTick_BASE        (0xE000E000UL +  0x0010UL)

struct SysTick_Type_s {
	volatile unsigned int CTRL;			/* SysTick 控制和状态寄存器 */
	volatile unsigned int LOAD;			/* SysTick 重加载计数值寄存器*/
	volatile unsigned int VAL;			/* SysTick 当前计数值寄存器 */
	volatile const  unsigned int CALIB;	/* SysTick 校正寄存器*/
} SysTick_Type;

#define SysTick             ((struct SysTick_Type_s *)SysTick_BASE)

#define SysTick_CTRL_COUNTFLAG_Pos		16U
#define SysTick_CTRL_COUNTFLAG_Msk		(1UL << SysTick_CTRL_COUNTFLAG_Pos)

#define SysTick_CTRL_CLKSOURCE_Pos		2U
#define SysTick_CTRL_CLKSOURCE_Msk		(1UL << SysTick_CTRL_CLKSOURCE_Pos)

#define SysTick_CTRL_TICKINT_Pos		1U
#define SysTick_CTRL_TICKINT_Msk		(1UL << SysTick_CTRL_TICKINT_Pos)

#define SysTick_CTRL_ENABLE_Pos			 0U
#define SysTick_CTRL_ENABLE_Msk			(1UL /*<< SysTick_CTRL_ENABLE_Pos*/)

static inline unsigned int SysTick_Config(unsigned int ticks)
{
	if ((ticks - 1UL) > 0xFFFFFFUL)
		return 1UL;

	SysTick->LOAD  = (unsigned int)(ticks - 1UL);

	/**
	 * 采用了默认的中断优先级
	 * 可以根据实际情况设置
	 */
	SysTick->VAL   = 0UL;
	SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
					SysTick_CTRL_TICKINT_Msk   |
					SysTick_CTRL_ENABLE_Msk;
	return 0UL;
}

static void init_time_cortexm3(void)
{
	SysTick_Config(configSYSTICK_CLOCK_HZ/configTICK_RATE_HZ);
}

static uint32_t arch_timer_rate;

uint32_t arch_timer_get_rate(void)
{
	return arch_timer_rate;
}

static void
arch_timer_detect_rate(void)
{
	arch_timer_rate = arch_timer_get_cntfrq();

	pr_debug("定时器初始化完毕，时钟频率：%d。\n",
	arch_timer_rate);
}


void init_time_arch(void);
void init_time_arch(void)
{
	arch_timer_detect_rate();
	init_time_cortexm3();
}

void init_timer_arch(void);
void init_timer_arch(void)
{
	MODULE_INIT(init_timer_arch);
}

void arch_timer_secondary_init(void)
{

}

int xilinx_ttc_int_status(int cpu, uint32_t countid)
{
	return 0;
}